package com.lse_from.control

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.google.gson.reflect.TypeToken
import com.lse_from.dto.FromData
import com.lse_from.dto.FromField
import com.lse_from.exception.LseException
import com.lse_from.service.FromDataService
import com.lse_from.service.FromFieldService
import com.lse_from.service.FromsService
import com.lse_from.utils.FieldUtil
import com.lse_from.utils.PubUtil
import com.lse_from.utils.PubVal
import com.lse_from.utils.ResponseResult
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.util.StringUtils
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import java.nio.charset.Charset
import java.time.LocalDateTime
import java.util.HashMap
import javax.annotation.Resource
import javax.servlet.http.HttpServletRequest
import javax.validation.constraints.NotBlank

/**
 * 表单数据控制
 *
 * @author 祁雪
 */
@Controller
@RequestMapping(value = arrayOf("/lse/api/fromdata"))
@Validated
class FromDataController : LseException(), PubVal {

    @Resource
    lateinit var request: HttpServletRequest

    @Autowired
    lateinit var fromsService: FromsService

    @Autowired
    lateinit var fromDataService: FromDataService

    @Autowired
    lateinit var fromFieldService: FromFieldService

    /**
     * 编辑or新建表单字段
     */
    @PostMapping(value = arrayOf("/ecfield"))
    @ResponseBody
    fun ecField(@Validated field: FromField): ResponseResult {

        field.id = field.fromId

        // 检查表单是否存在
        val from = fromsService.getById(field.fromId)
        if (from == null) {
            return ResponseResult.err("暂未读取到指定的表单", null)
        }

        /*var flag = PubUtil.checkJson(field.field.toString())

        if (!flag) {
            return ResponseResult.err("数据格式不正确", null)
        }*/

        val fields = FieldUtil.checkFieldHav(field = field.field!!, true)

        field.updateTime = LocalDateTime.now()

        val flag = fromFieldService.saveOrUpdate(field)

        return ResponseResult.custom(flag, if (flag) "保存成功" else "保存失败", fields)
    }

    /**
     * 读取表单字段实体数据
     */
    @GetMapping(value = arrayOf("/getfield/{fid}"))
    @ResponseBody
    fun getField(
        @NotBlank(message = "请选择表单")
        @PathVariable(value = "fid")
        fid: String
    ): ResponseResult {

        val from = fromsService.getById(fid)

        if (from == null) {
            return ResponseResult.err("暂未查询到表单信息", null)
        }

        val field = fromFieldService.getOne(QueryWrapper<FromField>().let {
            it.eq("from_id", from.id)
            it
        })

        var fields: List<Map<String, Any?>>? = null
        if (field != null) {
            fields = FieldUtil.checkFieldHav(field = field.field!!, false)
        }

        return ResponseResult.sucData(
            mapOf(
                "from" to from,
                "field" to field,
                "fields" to fields
            )
        )

    }

    /**
     * 保存或更新表单数据
     *
     * @author 祁雪
     */
    @PostMapping(value = arrayOf("/ecformdata/{fromId}"))
    @ResponseBody
    fun ecFormData(
        @Validated data: FromData,
        @NotBlank(message = "请选择表单")
        @PathVariable(value = "fromId")
        fromId: String
    ): ResponseResult {

        if (data.id.isNullOrBlank()) {
            data.id = PubUtil.getUUID()
        }

        data.fromId = fromId

        // 检查表单是否存在
        val from = fromsService.getById(data.fromId)
        if (from == null) {
            return ResponseResult.err("暂未读取到指定的表单", null)
        }

        data.updateTime = LocalDateTime.now()
        val flag = fromDataService.saveOrUpdate(data)

        return ResponseResult.custom(flag, if (flag) "保存成功" else "保存失败")

    }

    /**
     * 删除表单数据
     */
    @PostMapping(value = arrayOf("/delformdata/{form}"))
    @ResponseBody
    fun delFormData(
        @NotBlank(message = "请选择记录") id: String,
        @NotBlank(message = "请选择表单")
        @PathVariable(value = "form")
        form: String
    ): ResponseResult {

        val flag = fromDataService.remove(QueryWrapper<FromData>().let {
            it.eq("id", id)
                .eq("from_id", form)
            it
        })

        return ResponseResult.custom(flag, if (flag) "删除成功" else "删除失败")
    }

    /**
     * 根据表单分页读取数据
     */
    @GetMapping(value = arrayOf("/listformdata/{form}"))
    @ResponseBody
    fun listFormData(
        @NotBlank(message = "请选择表单")
        @PathVariable(value = "form")
        form: String,
        @RequestParam(defaultValue = PubVal.PAGENO) pageNo: Int,
        @RequestParam(defaultValue = PubVal.PAGESIZE) pageSize: Int
    ): ResponseResult {

        val page = fromDataService.page(Page(pageNo.toLong(), pageSize.toLong()),
            QueryWrapper<FromData>().let {
                it.eq("from_id", form)
                    .orderByDesc("update_time")
                it
            })
        val gson = PubUtil.getGson()
        val list = arrayListOf<Any>()
        page.records.forEach {
            val dataMap = gson.fromJson(
                it.fromDataJson,
                object : TypeToken<HashMap<String, Any>>() {}.type
            ) as HashMap<String, Any>
            dataMap.put(
                "otherInfo", mapOf(
                    "id" to it.id,
                    "formId" to it.fromId,
                    "createTime" to it.createTime,
                    "updateTime" to it.updateTime
                )
            )
            list.add(dataMap)
        }

        val resultPage = Page<Any>().let {
            it.records = list
            it.current = page.current
            it.size = page.size
            it.pages = page.pages
            it.total = page.total
            it
        }

        return ResponseResult.sucData(resultPage)
    }
}